import { join } from 'path';
import { readYaml } from './tool';
import { green, red, yellow } from 'kolorist';
import { IMessage } from 'qq-guild-bot';
import { existsSync, mkdirSync, readdirSync, watch, writeFileSync } from 'fs';
import lodash from 'lodash';

// 监听config/config.yaml
function watchC() {
  watch(join(process.cwd(), './config/config.yaml'), async (event, filename) => {
    setTimeout(async () => {
      const file = join(process.cwd(), './config/config.yaml');
      const config = readYaml(file);

      if (
        (config ?? '') === '' ||
        (config.account ?? '') === '' ||
        JSON.stringify(cfg) !== JSON.stringify(config.account)
      ) {
        console.warn(yellow(join(process.cwd(), './config/config.yaml') + ' 修改需要手动重启'));
        process.exit();
      }
    }, 500);
  });
}

// 消息处理
export async function dealMsg(e: { msg: IMessage }) {
  for (let val of command) {
    let msg = e.msg.content;
    if (!val.reg) {
      val.reg = 'noCheck';
    } else {
      // 去掉@机器人
      if (msg) {
        msg = msg.replace(`<@!${bot.id}>`, '').trim();
      }
    }
    if (new RegExp(val.reg).test(msg) || val.reg == 'noCheck') {
      let { type, name } = val;
      if (!Apps[type] || !Apps[type][name]) {
        console.error(red(`请先export该方法：${type}.${name}`));
        return;
      }

      try {
        let res = await Apps[type][name](e);
        if (res) {
          break;
        }
      } catch (error) {
        console.error(red(`${type}.${name}`));
        let err = JSON.stringify(error, null, 2);
        if (err + '' === '{}') {
          console.log(red(error));
        } else {
          console.log(red(err));
        }
        return;
      }
    }
  }
}

declare global {
  var Apps: {};
  var command: any[];
}
//加载功能
async function loadApp(dir: string[]) {
  let Apps = {};
  let command = [];
  for (let val of dir) {
    let readDir = readdirSync(val);
    readDir = readDir.filter(item => /.(js|ts)$/.test(item));
    for (let v of readDir) {
      let name = v.slice(0, v.lastIndexOf('.'));

      let tmp = await import(`${val}/${name}`).catch(error => {
        console.error(red(`报错：${v}`));
        console.error(error);
        process.exit();
      });
      if (!tmp) {
        return;
      }
      if (!tmp.rule) continue;
      Apps[name] = tmp;
      for (let i in tmp.rule) {
        tmp.rule[i].type = name;
        tmp.rule[i].name = i;
        command.push(tmp.rule[i]);
      }
    }
  }

  command = lodash.orderBy(command, ['priority'], ['asc']);
  global.Apps = Apps;
  global.command = command;
  saveCommand(command);
}

// 加载Plugin
async function loadPlugin(dir: string[]) {
  let Apps = global.Apps || {};
  let command = global.command || [];

  for (let val of dir) {
    if (!existsSync(val)) {
      mkdirSync(val, { recursive: true });
    }
    let readDir = readdirSync(val);
    for (let v of readDir) {
      if (!existsSync(`${val}/${v}/index.js`) && !existsSync(`${val}/${v}/index.ts`)) {
        continue;
      }

      let tmp = await import(`${val}/${v}/index`).catch(error => {
        console.error(red(`报错：${v}`));
        console.error(red(error));
        process.exit();
      });
      let rules = tmp.rule;
      if (!rules) {
        continue;
      }

      let type = v;
      Apps[type] = tmp;
      for (let i in rules) {
        rules[i].type = type;
        rules[i].name = i;
        rules[i]._plugin = type;
        command.push(tmp.rule[i]);
      }
    }
  }

  command = lodash.orderBy(command, ['priority'], ['asc']);

  global.Apps = Apps;
  global.command = command;

  saveCommand(command);
}
let comm = false;

//生成命令json
async function saveCommand(command: any[]) {
  let data = {
    dec: '命令总览json，只是查看，修改不起作用，需要到具体文件修改'
  };
  for (let val of command) {
    if (!data[val.type]) {
      data[val.type] = {};
    }

    data[val.type][val.name] = {
      reg: val.reg,
      priority: val.priority,
      describe: val.describe
    };
  }

  writeFileSync(join(process.cwd(), './config/command.json'), JSON.stringify(data, null, '\t'));
  if (!comm) {
    console.log(
      yellow('生成command.json成功,具体请看' + join(process.cwd(), './config/command.json'))
    );
    comm = true;
  }
}

export async function init() {
  // 加载插件
  const example = join(process.cwd(), './example');
  await loadApp([example]);
  const plugins = join(process.cwd(), './plugins');
  await loadPlugin([plugins]);
  console.info(green(`共成功加载${Object.keys(Apps).length}个插件`));

  watchC();
}
